<?php
/**
 * Created by PhpStorm.
 * User: admin
 * Date: 2019/1/15
 * Time: 23:05
 */
namespace app\common\library\task;


use app\common\library\CreateUser;
use app\common\model\User;
use app\common\model\zbtask\Money;
use app\common\model\zbtask\Order;
use app\common\model\zbtask\Rate;
use app\common\model\zbtask\Zbtask;
use app\common\utils\Utils;
use fast\Random;
use think\Db;
use think\exception\ValidateException;

/**
 * 导入众包费流程
 * 创建用户 ==》创建订单 ==》生成税率 ==》写入数据
 */
class ImportService
{

    static $Obj = null;
    private static $field = ['task_id', 'real_name', 'identity_card', 'bank_card', 'mobile', 'money', 'type', 'status', 'money_type','item','is_import'];
    static $orderModel = null;

    private $data = [];
    private $user = null;
    private $order = null;
    private $task = null;
    private function __construct() {
        self::$orderModel = new Order();
    }


    public static function instance () { //声明一个静态公共方法，供外部获取唯一实例
        if (!(self::$Obj instanceof self)) {
            self::$Obj = new self;
        }
        //获取新对象的时候 需要初始化 对象的数据
        self::$Obj->data = [];
        self::$Obj->user = null;
        self::$Obj->order = null;
        return self::$Obj;
    }

    /**
     * 创建数据
     * 此处可以对数进行过滤
     */
    public function setData($data) {
        $keys = array_keys($data);
        foreach (self::$field as $v) {
            if (!in_array($v, $keys)) {
                throw new ValidateException('导入的数据错误' . $v);
            }
        }

        if ($data['is_import'] == 1) {
            throw new ValidateException('不能重复导入');
        }
        if ($data['status'] != 1) {
            throw new ValidateException('数据有错误不能导入');
        }
        //检测下同一个人之前有没有
        $this->data = $data;

        return $this;
    }

    /**
     * 创建用户 一次创建一条数据
     */
    public function createUser() {
        if (!$this->data) {
            throw new ValidateException('请先创建要处理的数据');
        }
        $user = CreateUser::instance()->createData($this->data);
        if (!$user) {
            throw new ValidateException('创建用户失败');
        }

        $this->user = $user;
        $this->data = array_merge($this->data, ['user_id' => $user['id']]); //加入user_id
        return $this;
    }

    public function setTask($task) {
        if (!$task['id']) {
            throw new ValidateException('设置任务失败');
        }

        $this->task = $task;
        return $this;
    }
    /**
     * 创建订单
     */
    public function createOrder() {
        if (!$this->user) {
            throw new ValidateException('请先创建用户');
        }

        $task = Zbtask::get($this->data['task_id']);
        if (!$task) {
            throw new ValidateException('任务不正确');
        }
        $this->setTask($task);
        //不能重复接任务
        /*$order = self::$orderModel->get(['task_id'=>$this->data['task_id'], 'user_id'=>$this->user['id']]);
        if ($order) {
            throw new ValidateException('不能重复接取任务');
        }*/

        $data['user_id'] = $this->user['id'];
        $data['is_submit'] = 1;  //已确认
        $data['type'] = 2;       //已完成
        $data['task_id'] = $this->data['task_id'];
        $data['is_jiesuan'] = 1;  //已结算  因为导入众包费
        $data['createtime'] = $task['createtime'];
        $data['submittime'] = $task['createtime'];
        $data['send_time'] = $task['createtime'];
        $data['paytime'] = $task['createtime'];
        $data['company_id'] = $task['company_id'];
        $order = self::$orderModel->create($data);

        if (!$order) {
            throw new ValidateException('创建订单失败');
        }

        $this->order = $order;
        return $this;
    }

    /*导入众包费方法*/
    public function insertData() {
        if (!$this->order) {
            throw new ValidateException('请先创建订单');
        }
        if (!$this->order['createtime']) {
            throw new ValidateException('请先制定任务的创建时间');
        }
        $res = RateService::instance()->setData($this->data)->getOld($this->task['createtime'])->sureTax()->process(); //对本条数据进行解析
        $data['user_id'] = $this->user['id'];
        $data['order_id'] = $this->order['id'];
        $data['task_id'] = $this->order['task_id'];
        $data['ca_tax'] = config('site.money_tax_radio');
        $data['item'] = $this->data['item'];
        $data['createtime'] = $this->order['paytime'];  //结算时间
        $data['bank_card'] = $this->data['bank_card'];
        $data['pay_type'] = $this->data['type'];
        $data['company_id'] = $this->order['company_id'];
        $data['tax_money'] = $res['allTaxMoney'];
        $data['already_money'] = $res['allTaxMoney'];
        $data['json_rate'] = json_encode($res['json_rate']);
        $data['get_money'] = $res['get_money'];
        $data['money'] = $res['money'];
        $data['ca_money'] = $res['ca_money'];


        $taskMoney = Money::create($data);
        if (!$taskMoney) {
            throw new ValidateException('提交失败');
        }
        //生成税率
        $this->createRate($taskMoney);
        //启上数据
        $this->selectAllNeedChange($taskMoney);
        return true;
    }

    /**
     * 事务由商城控制
     * 删除或者驳回众包费之后重新创建税率
     * @param object $money
     * @param mixed $ids 要排除的id
     * @return object
     */
    public function delReRate($money, $ids = '') {
        $where = [];
        if ($ids) {
            $where['id'] = ['not in', $ids];  //排除删除的元素
        }
        $this->selectAllNeedChange($money, $where, $ids);
        return $this;
    }
    /**
     * 查询出需要变动的数据 这里只处理启上数据  其上数据的变动 是根据当前数据变动的
     * @param object $money
     * @param array $where   额外条件 查询启上条件
     * @param string $ids   要排除的id 计算税率
     * @return object $this
     */
    public function selectAllNeedChange($money, $where = [], $ids= '') {
        $where['user_id'] = $money['user_id'];
        $where['status'] = 1;
        $where['type'] = ['neq', 2];
        $where['id'] = ['neq', $money['id']];  //排除自身 启上数据不包括自身
        $beginTime = $money['createtime'];     //这个时间之后的 数据都需要重置  充值众包费税率的条件  众包费是按年生成的
        $endTime = mktime(0, 0, 0, 12, 31, date('Y', $beginTime));
        //今年的数据 先导入的数据 税率 小 后导入的税率大  需要重置税率的数据
        $list = Money::all(function ($query)use ($beginTime, $endTime, $where) {
            $query->where(['createtime' => ['egt', $beginTime]])->where($where)
                ->where(['createtime'=> ['elt', $endTime]])->order(['createtime'=>'asc','id'=>'asc']);
        });
        //重置数据
        foreach ($list as $k => $v) {
            if ($v['createtime'] == $money['createtime'] ) {
                if ($money['id'] > $v['id']) {
                    continue;
                }
            }

            $v['money_type'] = 2;  //通过实发进行推到，因为应发不准确
            $v['money'] = $v['get_money'];  //通过实发进行推到，因为应发不准确
            $this->reRate($v, $ids);
        }

        return $this;
    }
    /**
     * 重制税率
     * @param object $money
     * @param string $ids  要排除统计的
     * @return object $this
     */
    public function reRate($money, $ids = '') {
        //同一时刻，相同的的众包费，根据id的先后顺序进行统计 前面的统计 后面的不统计
        $cur = Money::where([
            'createtime' => $money['createtime'],
            'user_id'=> $money['user_id'],
            'id'=>['egt', $money['id']]
        ])->column('id');
        if (!is_array($ids) && $ids) {
            $ids = Utils::explodeStr($ids);
        }
        if (!$ids) {
            $ids = [];
        }
        $cur = array_merge($ids, $cur);  //合并要排除的ids
        $map['id'] = ['not in', $cur];
        //这些数据的众包费和税率 需要重置  排除要删除数据的统计
        $res = RateService::instance()->setData($money)->getOld($money['createtime'], $map)->sureTax()->process(); //对本条数据进行解析
        //更新当前众包费信息
        $money->tax_money = $res['allTaxMoney'];
        $money->already_money = $res['allTaxMoney'];
        $money->json_rate = json_encode($res['json_rate']);
        $money->get_money = $res['get_money'];
        $money->money = $res['money'];
        $money->ca_money = $res['ca_money'];
        $money->ca_tax = config('site.money_tax_radio');
        $money->allowField(true)->save();
        //生成税率
        $this->createRate($money);

        return $this;
    }
    /**
     * 生成税率，写入税率表
     * 表示生成一条众包费的税率
     * $data 代表众包费数据
     */
    public function createRate($data) {
        if (!$this->task) {
            if (!$data['task_id']) {
                throw new ValidateException('请先设置任务');
            }

            $this->task = Zbtask::get($data['task_id']);
            if (!$this->task) {
                throw new ValidateException('请先设置任务');
            }
        }
        //生成之前先删除之前的税率
        $rate = json_decode($data['json_rate'], true);
        $all = [];
        $this->delete($data['id']);
        foreach ($rate as $k => $v) {
            $temp['task_money_id'] = $data['id'];
            $temp['ca_tax'] = $data['ca_tax'];
            $temp['createtime'] = $data['createtime'];  //跟众包时间保持一致
            $temp['user_id'] = $data['user_id'];
            $temp['money'] = $v['tax_money'];
            $temp['ca_money'] = $v['ca_money'];
            $temp['tax_rate'] = $v['tax_rate'];
            $temp['kouchushu'] = $v['kouchushu'];
            $temp['company_id'] = $this->task['company_id'];
            array_push($all, $temp);
        }

        $rate = model('common/zbtask.Rate');
        $res = $rate->saveAll($all);
        if ($res === false) {
            throw new ValidateException('生成税率失败');
        }

        return true;
    }

    /**
     * 删除税率
     * $money_id
     */
    public function delete($money_id) {
        if (!$money_id) {
            throw new ValidateException('请传递众包费ID');
        }
        $rate = model('common/zbtask.Rate');
        $res = $rate->where(['task_money_id'=> $money_id])->delete();
        if ($res === false) {
            throw new ValidateException('删除失败');
        }
        return true;
    }



    private function __clone() {} //声明私有的克隆方法，防止对象被克隆

    public function __sleep() { //重写__sleep方法，将返回置空，防止序列化反序列化获得新的对象
        return [];
    }

}